package org.jeecg.modules.common.config.mqtt;
import java.util.Date;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.aliyuncs.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.common.CamelliaConstants;
import org.jeecg.modules.common.bean.influx.*;
import org.jeecg.modules.common.bean.mqtt.MqttCamelliaStatusBean;
import org.jeecg.modules.common.bean.mqtt.MqttControlBean;
import org.jeecg.modules.common.entity.CamelliaDevice;
import org.jeecg.modules.common.service.ICamelliaDeviceService;
import org.jeecg.modules.common.service.InFluxDBService;
import org.jeecg.modules.common.service.MqttGateway;
import org.jeecg.modules.common.task.TimeTask;
import org.jeecg.modules.common.utils.CamelliaDeviceStatusChanger;
import org.jeecg.modules.demo.mes.entity.ManageDevice;
import org.jeecg.modules.demo.mes.service.IManageDeviceService;
import org.jeecg.modules.env.entity.CamelliaEnvSys;
import org.jeecg.modules.env.entity.CamelliaEnvWarning;
import org.jeecg.modules.env.entity.CamelliaWarnMqttPayLoadBean;
import org.jeecg.modules.env.service.ICamelliaEnvWarningService;
import org.jeecg.modules.maintain.entity.CamelliaDeviceReport;
import org.jeecg.modules.maintain.service.ICamelliaDeviceReportService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.Message;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.Nullable;
import javax.annotation.Resource;
import java.time.Instant;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Component
public class MqttReceiveHandle {

    @Resource
    private InFluxDBService inFluxDBService;
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Resource
    private ICamelliaEnvWarningService camelliaEnvWarningService;

    @Resource
    private ICamelliaDeviceService camelliaDeviceService;
    @Resource
    private MqttGateway mqttGateway;
    @Resource
    private IManageDeviceService manageDeviceService;

    @Resource
    private ICamelliaDeviceReportService camelliaDeviceReportService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private CamelliaDeviceStatusChanger camelliaDeviceStatusChanger;
    private AtomicInteger adonRunningAtomic = new AtomicInteger(0);
    private AtomicBoolean ventAtomic = new AtomicBoolean(false);
    private AtomicBoolean sprayAtomic = new AtomicBoolean(false);
    private AtomicBoolean estopAtomic = new AtomicBoolean(false);

    private AtomicBoolean alarmAtomic = new AtomicBoolean(false);


    public void handle(Message<?> message) {
        String topic = String.valueOf(message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC));
        String payload = String.valueOf(message.getPayload());
        String clientId = topic.split("/")[1];
        if (StringUtils.isEmpty(clientId)) {
            return;
        }
        log.info("接收到 mqtt消息，主题:{} 消息:{}", topic, payload);

        threadPoolTaskExecutor.execute(new Runnable() {
            @Override
            public void run() {
                detachMqttTopicTask(clientId,topic,payload);
            }
        });




    }

    public void detachMqttTopicTask(String clientId,String topic,String payload){
        if (topic.contains(CamelliaConstants.TOPIC_TYPE_DATA_POST)) {
            insertPlayLoad(clientId, payload);
        } else if (topic.contains(CamelliaConstants.TOPIC_TYPE_EVENT_POST)) {
            CamelliaWarnMqttPayLoadBean camelliaWarnMqttPayLoadBean =
                    JSON.parseObject(payload, CamelliaWarnMqttPayLoadBean.class);
            if (camelliaWarnMqttPayLoadBean.getWarn() == 1) {
                if (alarmAtomic.compareAndSet(false, true)) {
                    insertAlarmEvent(clientId,payload,null,null);
                }
            }else {
                alarmAtomic.set(false);
            }
        } else if (topic.contains(CamelliaConstants.TOPIC_TYPE_CONTROL_REQUEST)) {

        } else if (topic.contains(CamelliaConstants.TOPIC_TYPE_CONTROL_RESPONSE)) {

        } else if (topic.contains(CamelliaConstants.TOPIC_TYPE_SYS_SET)) {

        } else if (topic.contains(CamelliaConstants.TOPIC_TYPE_SYS_ASK)) {

        } else if (topic.contains(CamelliaConstants.TOPIC_TYPE_NTP_REQUEST)) {

        } else if (topic.contains(CamelliaConstants.TOPIC_TYPE_NTP_RESPONSE)) {

        }

    }

    /**
     * 插入数据influxdb数据库
     * @param clientId
     * @param payload
     */
    public void insertPlayLoad(String clientId,String payload){
        /*
        设备类型
         */
        Integer value = TimeTask.deviceMap.get(clientId);
        if (value == null) {
            return;
        }
        if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_ENV){
            Env env = JSON.parseObject(payload, Env.class);
            env.setClientId(clientId);
            env.setTime(Instant.now());
            inFluxDBService.insert(env);
        }else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_DTU){
            if (clientId.equals("eqt_01")) {
                return;
            }

            MqttCamelliaStatusBean mqttCamelliaStatusBean = JSON.parseObject(payload, MqttCamelliaStatusBean.class);
            CamelliaDeviceStatus camelliaDeviceStatus = new CamelliaDeviceStatus();
            camelliaDeviceStatus.setClientId(clientId);
            camelliaDeviceStatus.setWater_tank_current(mqttCamelliaStatusBean.getWaterTank().getCurrent());
            camelliaDeviceStatus.setWater_tank_power(mqttCamelliaStatusBean.getWaterTank().getPower());
            camelliaDeviceStatus.setCompressor_current(mqttCamelliaStatusBean.getCompressor().getCurrent());
            camelliaDeviceStatus.setCompressor_power(mqttCamelliaStatusBean.getCompressor().getPower());
            camelliaDeviceStatus.setVacuum_pump_current(mqttCamelliaStatusBean.getVacuumPump().getCurrent());
            camelliaDeviceStatus.setVacuum_pump_power(mqttCamelliaStatusBean.getVacuumPump().getPower());
            camelliaDeviceStatus.setSolvent_pump_current(mqttCamelliaStatusBean.getSolventPump().getCurrent());
            camelliaDeviceStatus.setSolvent_pump_power(mqttCamelliaStatusBean.getSolventPump().getPower());
            camelliaDeviceStatus.setWater_pump_current(mqttCamelliaStatusBean.getWaterPump().getCurrent());
            camelliaDeviceStatus.setWater_pump_power(mqttCamelliaStatusBean.getWaterPump().getPower());
            camelliaDeviceStatus.setAir_compressor_current(mqttCamelliaStatusBean.getAirCompressor().getCurrent());
            camelliaDeviceStatus.setAir_compressor_power(mqttCamelliaStatusBean.getAirCompressor().getPower());
            camelliaDeviceStatus.setRefrigerator_current(mqttCamelliaStatusBean.getRefrigerator().getCurrent());
            camelliaDeviceStatus.setRefrigerator_power(mqttCamelliaStatusBean.getRefrigerator().getPower());
            camelliaDeviceStatus.setCamellia_device_current(mqttCamelliaStatusBean.getCamelliaDevice().getCurrent());
            camelliaDeviceStatus.setCamellia_device_power(mqttCamelliaStatusBean.getCamelliaDevice().getPower());
            camelliaDeviceStatus.setTime(Instant.now());
            inFluxDBService.insert(camelliaDeviceStatus);
            camelliaDeviceStatusChanger.camelliaDeviceStatus(mqttCamelliaStatusBean.getCamelliaDevice().getState(),
                                                            mqttCamelliaStatusBean.getRefrigerator().getState(),
                                                            mqttCamelliaStatusBean.getAirCompressor().getState(),
                                                            mqttCamelliaStatusBean.getWaterPump().getState(),
                                                            mqttCamelliaStatusBean.getSolventPump().getState(),
                                                            mqttCamelliaStatusBean.getVacuumPump().getState(),
                                                            mqttCamelliaStatusBean.getCompressor().getState(),
                                                            mqttCamelliaStatusBean.getWaterTank().getState());
            stringRedisTemplate.opsForValue().set("CAMELLIA:CAMELLIA_DEVICE_STATUS", mqttCamelliaStatusBean.getCamelliaDevice().getState() + "");
        }else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_LEAK){
            Leak leak = JSON.parseObject(payload, Leak.class);
            leak.setClientId(clientId);
            leak.setTime(Instant.now());
            inFluxDBService.insert(leak);

        } else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_MONITOR) {
        } else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_FIRE) {

        } else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_SMOKE) {
            Smoke smoke = JSON.parseObject(payload, Smoke.class);
            smoke.setTime(Instant.now());
            smoke.setClientId(clientId);
            inFluxDBService.insert(smoke);

        } else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_CRAFTSMANSHIP) {
        } else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_SAFE) {
            Safe safe = JSON.parseObject(payload, Safe.class);
            if (safe.getAndon()!=0&&safe.getAndon() !=adonRunningAtomic.get()) {
                if (safe.getAndon() == 1) {
                    insertAlarmEvent(clientId,payload,"13","黄灯亮");
                } else if (safe.getAndon() == 2) {
                    insertAlarmEvent(clientId,payload,"13","红灯亮蜂鸣器响");
                } else if (safe.getAndon() == 3) {
                    insertAlarmEvent(clientId,payload,"13","消音");
                }
                adonRunningAtomic.set(safe.getAndon());
            }
            if (safe.getVent() == 1) {
                if (ventAtomic.compareAndSet(false, true)) {
                    insertAlarmEvent(clientId,payload,"14","抽风系统启动");
                }

            }else {
                ventAtomic.set(false);
            }
            if (safe.getSpray() == 1) {
                if (sprayAtomic.compareAndSet(false,true)) {
                    insertAlarmEvent(clientId,payload,"15","喷淋系统启动");
                }

            }else {
                sprayAtomic.set(false);
            }
            if (safe.getEstop() == 1) {
                if (estopAtomic.compareAndSet(false, true)) {
                    insertAlarmEvent(clientId,payload,"16","急停系统启动");
                }
            }else {
                estopAtomic.set(false);
            }
        }


    }

    /**
     * 插入监测数值超过阈值数据
     */
    public void insertAlarmEvent(String clientId, String payload, @Nullable String indicate,@Nullable String reason){
        List<CamelliaDevice> deviceList = camelliaDeviceService.list();
        List<CamelliaEnvSys> camelliaEnvSysList = TimeTask.camelliaEnvSysList;
        CamelliaWarnMqttPayLoadBean camelliaWarnMqttPayLoadBean =
                JSON.parseObject(payload, CamelliaWarnMqttPayLoadBean.class);
        int sysCode = 0;
        Integer value = TimeTask.deviceMap.get(clientId);
        String warningReason = "";
        String warningIndicate = "";
        if (value == null) {
            return;
        }
        if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_ENV){
            int warnCode = camelliaWarnMqttPayLoadBean.getWarn();
            switch (warnCode) {
                case 0:
                    return;
                case 1:
                    warningReason = "温度监测数值超过阈值";
                    warningIndicate = "1";
                    break;
                case 2:
                    warningReason = "湿度监测数值超过阈值";
                    warningIndicate = "2";
                    break;
                case 3:
                    warningReason = "CO监测数值超过阈值";
                    warningIndicate = "3";
                    break;
                case 4:
                    warningReason = "CO2监测数值超过阈值";
                    warningIndicate = "4";
                    break;
                case 5:
                    warningReason = "PM2.5监测数值超过阈值";
                    warningIndicate = "5";
                    break;
                case 6:
                    warningReason = "PM10监测数值超过阈值";
                    warningIndicate = "6";
                    break;
                case 7:
                    warningReason = "噪声监测数值超过阈值";
                    warningIndicate = "7";
                    break;
                case 8:
                    warningReason = "大气压力监测数值超过阈值";
                    warningIndicate = "8";
                    break;
                default:
                    break;
            }
            sysCode = 0;
        }else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_DTU){

            List<String> reasonList = JSON.parseArray(payload, String.class);
            sysCode = 1;
            warningReason = "设备故障: " + reasonList.get(0);
            warningIndicate = "暂无";
            String deviceCode = "SB2508456235";
            CamelliaDeviceReport camelliaDeviceReport = new CamelliaDeviceReport();
            camelliaDeviceReport.setReportCode("BX" + DateUtils.getDate("yyyyMMdd") + RandomUtil.randomNumbers(4));
            camelliaDeviceReport.setUserName("系统报修");
            camelliaDeviceReport.setDeviceAddress(2);
            camelliaDeviceReport.setDeviceCode(deviceCode);
            camelliaDeviceReport.setState(0);
            camelliaDeviceReport.setProblemDesc(reasonList.get(0));
            camelliaDeviceReportService.save(camelliaDeviceReport);
            ManageDevice byDeviceCode = manageDeviceService.getByDeviceCode(deviceCode);
            byDeviceCode.setState(2);
            manageDeviceService.updateById(byDeviceCode);

        }else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_LEAK){
            int warnCode = camelliaWarnMqttPayLoadBean.getWarn();
            sysCode = 2;
            switch (warnCode) {
                case 0:
                    return;
                case 1:
                    warningReason = "泄露监测数值超过阈值";
                    warningIndicate = "9";
                    break;
                default:
                    break;
            }
        } else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_MONITOR) {
            sysCode = 3;
            int warnCode = camelliaWarnMqttPayLoadBean.getStatus();
            switch (warnCode) {
                case 0:
                    return;
                case 1:
                    warningReason = "非法入侵";
                    warningIndicate = "12";
                    //报警处理
                    try {
                        mqttGateway.sendToMqtt("/sys/control/request", JSON.toJSONString(new MqttControlBean(2)));
                    } catch (Exception e) {
                        log.error(e.getMessage());
                    }
                    break;
                default:
                    break;
            }
        } else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_SAFE) {
            sysCode = 4;
            warningIndicate = indicate;
            warningReason = reason;

        } else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_FIRE) {
            int warnCode = camelliaWarnMqttPayLoadBean.getWarn();
            switch (warnCode) {
                case 0:
                    return;
                case 1:
                    warningReason = "火灾监测数值超过阈值";
                    warningIndicate = "11";
                    break;
                default:
                    break;
            }
            sysCode = 5;
        } else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_SMOKE) {
            sysCode = 5;
            int warnCode = camelliaWarnMqttPayLoadBean.getWarn();
            switch (warnCode) {
                case 0:
                    return;
                case 1:
                    warningReason = "烟雾监测数值超过阈值";
                    warningIndicate = "10";
                    break;
                default:
                    break;
            }
        } else if (value == CamelliaConstants.CAMELLIA_DEVICE_TYPE_CRAFTSMANSHIP) {

        }
        CamelliaEnvWarning camelliaEnvWarning = new CamelliaEnvWarning();
        camelliaEnvWarning.setSystemCode(String.valueOf(sysCode));
        camelliaEnvWarning.setWarningIndicate(warningIndicate);
        camelliaEnvWarning.setWarningReason(warningReason);
        camelliaEnvWarning.setMonitoringValue(0.0D);
        camelliaEnvWarning.setThresholdValue(0.0D);
        camelliaEnvWarning.setPicUrl("");
        camelliaEnvWarning.setWarningDateTime(new Date());
        camelliaEnvWarning.setCreateTime(new Date());
        camelliaEnvWarning.setUpdateTime(new Date());
        camelliaEnvWarning.setIsDeleted(0);
        camelliaEnvWarningService.save(camelliaEnvWarning);
    }


}
